﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;

namespace Wintellect.LiveFx.Cloudboard
{
  /// <summary>
  /// Interaction logic for BusyIndicator.xaml
  /// </summary>
  public partial class BusyIndicator : UserControl
  {
    private const int RotationDuration = 1000;
    private const int NumTicks = 12;
    private const int BusyTickRadius = 8;

    private Storyboard spinAnimation;

    public BusyIndicator()
    {
      InitializeComponent();
      this.BuildBusyIndicator();
    }

    private void BuildBusyIndicator()
    {
      double renderRadius = ((this.Height > this.Width) ? this.Width : this.Height) / 2 - BusyIndicator.BusyTickRadius;
      for (double currentAngle = 0D; currentAngle < 2 * Math.PI; currentAngle += (2D * Math.PI) / BusyIndicator.NumTicks)
      {
        // The offset angle we want to start at
        double tickAngle = currentAngle + Math.PI / 2D;

        Ellipse tick = new Ellipse();
        tick.Fill = new SolidColorBrush(Colors.White);
        tick.Opacity = 1D - currentAngle / (2 * Math.PI);
        tick.Height = 2 * BusyIndicator.BusyTickRadius;
        tick.Width = 2 * BusyIndicator.BusyTickRadius;

        double top = (this.Height / 2) - (Math.Sin(tickAngle) * renderRadius) - BusyIndicator.BusyTickRadius;
        double left = (this.Width / 2) - (Math.Cos(tickAngle) * renderRadius) - BusyIndicator.BusyTickRadius;
        tick.SetValue(Canvas.TopProperty, top);
        tick.SetValue(Canvas.LeftProperty, left);

        this.layout.Children.Add(tick);
      }

      this.layout.RenderTransform = new RotateTransform(0, this.Width/2, this.Height/2);
      this.RenderTransformOrigin = new Point(.5, .5);

      this.spinAnimation = new Storyboard();
      this.spinAnimation.RepeatBehavior = RepeatBehavior.Forever;
      DoubleAnimationUsingKeyFrames rotationAnimation = new DoubleAnimationUsingKeyFrames();
      for (double position = 0; position <= 360D; position += 360D/BusyIndicator.NumTicks)
      {
        DoubleKeyFrame currentFrame = new DiscreteDoubleKeyFrame(position);
        currentFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(BusyIndicator.RotationDuration * position/360D));
        currentFrame.Value = -1 * position;
        rotationAnimation.KeyFrames.Add(currentFrame);
      }
      rotationAnimation.Duration = TimeSpan.FromMilliseconds(BusyIndicator.RotationDuration);
      Storyboard.SetTarget(rotationAnimation, this.layout);
      Storyboard.SetTargetProperty(rotationAnimation, new PropertyPath("(UIElement.RenderTransform).(RotateTransform.Angle)"));
      this.spinAnimation.Children.Add(rotationAnimation);
    }

    private void BusyIndicator_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
      if (this.IsVisible)
      {
        if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
        {
          this.spinAnimation.Begin();
        }
      }
      else
      {
        this.spinAnimation.Stop();
      }
    }
  }
}
